home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Belgian Amiga Club - ADF Collection
/
BS1 part 41.zip
/
BS1 part 41
/
Amiga Plus 1.adf
/
Programming
/
menustuf.c
< prev
next >
Wrap
C/C++ Source or Header
|
1978-04-08
|
12KB
|
457 lines
/* :ts=8 */
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
/* */
/* MenuStuf.c */
/* */
/* Menu routines for AmigaPLUS article about Intuition */
/* Written by Michael G. Lehman */
/* of Intuitive Technologies */
/* */
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
/* Complete Include file for Amiga programs */
/* Derived from examples supplied by Commodore Amiga */
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
#include <exec/types.h>
#include <exec/nodes.h>
#include <exec/lists.h>
#include <exec/memory.h>
#include <exec/ports.h>
#include <exec/tasks.h>
#include <exec/libraries.h>
#include <exec/devices.h>
#include <exec/io.h>
#include <exec/devices.h>
#include <libraries/dos.h>
#include <graphics/gfx.h> /* ALWAYS INCLUDE GFX.H before other includes */
#include <graphics/display.h>
#include <graphics/clip.h>
#include <graphics/rastport.h>
#include <graphics/gfxbase.h>
#include <graphics/text.h>
#include <graphics/regions.h>
#include <graphics/copper.h>
#include <graphics/gels.h>
#include <devices/inputevent.h>
#include <devices/gameport.h>
#include <devices/console.h>
#include <devices/keymap.h>
#define int32 long
#define int16 int
#include <intuition/intuition.h>
struct XMenuItem /* our extended menu structure */
{
struct XMenuItem *NextItem;
SHORT LeftEdge, TopEdge;
SHORT Width, Height;
USHORT Flags;
LONG MutualExclude;
APTR ItemFill;
APTR SelectFill;
BYTE Command;
struct XMenuItem *SubItem;
USHORT NextSelect;
int (*ItemHndlr)(); /* all above is standard and we add this */
};
extern UBYTE * AllocMem();
#define SECONDS io_Actual
#define MICROSECONDS io_Length
#define PUBCLEAR MEMF_CHIP | MEMF_CLEAR
struct Menu *NewMenu();
struct XMenuItem *AddItem();
struct XMenuItem *AddSubItem();
extern struct Window *Mwindow; /* currently chosen window and screen for */
extern struct Screen *Mscreen; /* this menu build operation */
#define ITEMSTD ITEMTEXT | ITEMENABLED | HIGHCOMP
#define CHKITEMSTD ITEMSTD | CHECKIT
/****************************************************************/
/* */
/* NewMenu */
/* Build a menu header */
/* LeftEdge automatically calcuated if passed as -1 */
/* Width automatically calculated if passed as -1 */
/* */
/* Returns pointer to the Menu for calling AddItem */
/* */
/****************************************************************/
struct Menu *NewMenu(root,left,top,width,height,flags,title)
struct Menu *root;
int32 left,top,width,height,flags;
register char *title;
{
register int32 i;
register struct Menu *p;
register struct Menu *p2;
p = AllocMem(sizeof(struct Menu),PUBCLEAR);
p2 = NULL;
if (root != NULL)
{
p2 = root /* -> NextMenu */ ;
while(p2->NextMenu !=NULL)
p2 = p2 -> NextMenu;
}
if (p2 != NULL)
p2 -> NextMenu = p;
p -> NextMenu = NULL;
if (left == -1 && p2 != NULL)
p -> LeftEdge = p2 -> LeftEdge + p2 -> Width + 6;
else
p -> LeftEdge = left;
p -> TopEdge = top;
if (width == -1)
p -> Width = TextLength(&Mscreen -> RastPort,title,strlen(title))+10;
else
p -> Width = width;
p -> Height = height;
p -> Flags = flags;
p -> FirstItem = NULL;
p -> MenuName = title;
return(p);
}
/****************************************************************/
/* */
/* AddItem */
/* Add a menu item to a menu list */
/* Width and Height automatically calculated */
/* */
/* Returns pointer to the item for calling AddSubItem */
/* */
/****************************************************************/
struct XMenuItem *AddItem(mp,flags,text,handler,cmdchar)
struct Menu *mp;
int32 flags;
char *text;
int32 (*handler)(); /* subroutine to handle this menu item */
char cmdchar; /* valid only if flags & COMMSEQ is true */
{
register struct XMenuItem *mp2;
register struct XMenuItem *mi;
register struct IntuiText *ip;
register int32 i;
int32 maxwidth;
i = 0;
if (mp -> FirstItem != NULL)
{
mp2 = mp -> FirstItem;
i++;
while(mp2 -> NextItem != NULL)
{
i++;
mp2 = mp2 -> NextItem; /* get to the bottom of the list */
}
}
else
mp2 = NULL; /* so our debug stuff doesn't blow up */
mi = AllocMem(sizeof(struct XMenuItem),PUBCLEAR);/*this zeroes it as well */
ip = (struct IntuiText *) AllocMem(sizeof(struct IntuiText),PUBCLEAR);
ip -> FrontPen = 0;
ip -> BackPen = Mwindow -> BlockPen;
ip -> DrawMode = JAM2;
ip -> LeftEdge = 0;
ip -> TopEdge = 1;
ip -> ITextFont = NULL;
ip -> NextText = NULL;
ip -> IText = text;
mi -> NextItem = NULL;
mi -> LeftEdge = 0;
mi -> TopEdge = /*12*/ 9 * i; /* standard height = 12 lines */
mi -> Width = IntuiTextLength(ip);
if (flags & COMMSEQ)
mi -> Width += COMMWIDTH;
mi -> Height= /*12*/ 9; /* standard height = 12 lines */
mi -> Flags = flags;
mi -> MutualExclude = 0;
mi -> ItemFill = (APTR) ip;
mi -> SelectFill = NULL;
mi -> Command = 0;
mi -> SubItem = NULL;
mi -> NextSelect = 0;
mi -> ItemHndlr = handler;
if (flags & COMMSEQ)
mi -> Command = cmdchar;
if (i == 0)
mp -> FirstItem = mi;
else
mp2 -> NextItem = mi;
/* now run the menu list looking for the widest */
mp2 = mp -> FirstItem;
maxwidth = mp2 -> Width;
while(mp2 -> NextItem != NULL)
{
mp2 = mp2 -> NextItem;
if (mp2 -> Width > maxwidth)
maxwidth = mp2 -> Width;
}
if (maxwidth <= mp -> Width)
maxwidth = mp -> Width;
/* now set all items to the max width */
mp2 = mp -> FirstItem;
while(mp2 != NULL)
{
mp2 -> Width = maxwidth;
mp2 = mp2 -> NextItem;
}
SetMaximumWidth(mp);
return(mi);
}
/****************************************************************/
/* */
/* AddSubItem */
/* Add a sub menu item to a menu item */
/* Width and Height automatically calculated */
/* */
/* Returns pointer for adding sub-sub items */
/* */
/****************************************************************/
struct XMenuItem *AddSubItem(mp,flags,text,cmdchar)
struct XMenuItem *mp;
int32 flags;
char *text;
char cmdchar; /* valid only if flags & COMMSEQ is true */
{
register struct XMenuItem *mp2;
register struct XMenuItem *mi;
register struct IntuiText *ip;
register int32 i;
int32 maxwidth;
i = 0;
if (mp -> SubItem != NULL)
{
mp2 = mp -> SubItem;
i++;
while(mp2 -> NextItem != NULL)
{
i++;
mp2 = mp2 -> NextItem; /* get to the bottom of the list */
}
}
mi = AllocMem(sizeof(struct XMenuItem),PUBCLEAR);/* this zeroes it as well */
ip = (struct IntuiText *) AllocMem(sizeof(struct IntuiText),PUBCLEAR);
ip -> FrontPen = 0;
ip -> BackPen = Mwindow -> BlockPen;
ip -> DrawMode = JAM2;
ip -> LeftEdge = 0;
ip -> TopEdge = 1;
ip -> ITextFont = NULL;
ip -> NextText = NULL;
ip -> IText = text;
mi -> NextItem = NULL;
mi -> LeftEdge = mp -> LeftEdge + mp -> Width -2;
mi -> TopEdge = /*12*/ 9 * i; /* standard height = 12 lines */
mi -> Width = IntuiTextLength(ip);
if (flags & COMMSEQ)
mi -> Width += COMMWIDTH;
mi -> Height= /*12*/ 9; /* standard height = 12 lines */
mi -> Flags = flags;
mi -> MutualExclude = 0;
mi -> ItemFill = (APTR) ip;
mi -> SelectFill = NULL;
mi -> Command = 0;
mi -> SubItem = NULL;
mi -> ItemHndlr = mp -> ItemHndlr; /* copy from the parent menu */
mi -> NextSelect = 0;
if (flags & COMMSEQ)
mi -> Command = cmdchar;
if (i == 0)
mp -> SubItem = mi;
else
mp2 -> NextItem = mi;
/* now run the menu list looking for the widest */
mp2 = mp -> SubItem;
maxwidth = mp2 -> Width;
while(mp2 -> NextItem != NULL)
{
mp2 = mp2 -> NextItem;
if (mp2 -> Width > maxwidth)
maxwidth = mp2 -> Width;
}
/* now set all items to the max width */
mp2 = mp -> SubItem;
while(mp2 != NULL)
{
mp2 -> Width = maxwidth;
mp2 = mp2 -> NextItem;
}
return(mi);
}
/****************************************************************/
/* */
/* UnMakeMenuStrip(rmp) */
/* */
/* Takes as input a "root menu pointer" i.e. the pointer */
/* from the Window record */
/* calls as needed: */
/* UnMakeMenu */
/* UnMakeItem */
/* UnMakeSubItem */
/****************************************************************/
void UnMakeMenu();
void UnMakeItem();
void UnMakeSubItem();
void UnMakeMenuStrip(rmp)
struct Menu *rmp;
{
register struct Menu *mp,*mp2;
if (rmp == NULL)
return;
mp = rmp;
while(mp)
{
mp2 = mp -> NextMenu;
UnMakeMenu(mp); /* deallocate each menu in turn */
mp = mp2;
}
}
void UnMakeMenu(mp)
struct Menu *mp;
{
register struct XMenuItem *mip,*mip2;
if (mp == NULL)
return;
mip = mp -> FirstItem;
while(mip)
{
mip2 = mip -> NextItem;
UnMakeItem(mip);
mip = mip2;
}
FreeMem(mp,sizeof(struct Menu));
}
void UnMakeSubItem(mip)
struct XMenuItem *mip;
{
if (mip == NULL)
return;
FreeMem(mip -> ItemFill,sizeof(struct IntuiText));
FreeMem(mip, sizeof(struct XMenuItem));
}
int32 ScanForMaxWidth(Menu)
struct Menu *Menu;
{
register int32 width = 0;
register struct XMenuItem *MenuItem;
MenuItem = Menu -> FirstItem;
while ( MenuItem ) {
if ( MenuItem -> Width > width ) width = MenuItem -> Width;
MenuItem = MenuItem -> NextItem;
}
return ( width );
}
SetMaximumWidth(Menu)
struct Menu *Menu;
{
register struct XMenuItem *MenuItem,*SubMenu;
int32 MaxWidth;
MaxWidth = ScanForMaxWidth ( Menu );
MenuItem = Menu -> FirstItem;
while ( MenuItem ) {
SubMenu = MenuItem -> SubItem;
while ( SubMenu ) {
SubMenu -> LeftEdge = MaxWidth;
SubMenu = SubMenu -> NextItem;
}
MenuItem -> Width = MaxWidth;
MenuItem = MenuItem -> NextItem;
}
}
void UnMakeItem(mip)
struct MenuItem *mip;
{
register struct MenuItem *mip2,*mip3;
if (mip == NULL)
return;
mip2 = mip -> SubItem;
while(mip2)
{
mip3 = mip2 -> NextItem;
UnMakeSubItem(mip2);
mip2 = mip3;
}
FreeMem(mip -> ItemFill,sizeof(struct IntuiText));
FreeMem(mip, sizeof(struct XMenuItem));
}